package com.zmzncs.lmtc.module.park.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zmzncs.lmtc.common.util.WeChatUtil;
import com.zmzncs.lmtc.common.pojo.AuthorizeVO;
import com.zmzncs.lmtc.common.pojo.LoginUser;
import com.zmzncs.lmtc.common.util.*;
import com.zmzncs.lmtc.module.park.dao.ManagerLinkDao;
import com.zmzncs.lmtc.module.park.dao.ParkManagerDao;
import com.zmzncs.lmtc.module.park.pojo.manager_link.ManagerLink;
import com.zmzncs.lmtc.module.park.pojo.manager_link.ManagerLinkDTO;
import com.zmzncs.lmtc.module.park.pojo.park_manager.LoginForm;
import com.zmzncs.lmtc.module.park.pojo.park_manager.*;
import com.zmzncs.lmtc.module.park.service.ParkManagerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.zmzncs.lmtc.module.park.dao.ManagerExpandDao;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;


/**
 * <p>
 * 车场管理员表 服务实现类
 * </p>
 *
 * @author 任建波
 * @since 2020-12-09
 */
@Service
@Slf4j
public class ParkManagerServiceImpl extends ServiceImpl<ParkManagerDao, ParkManager> implements ParkManagerService {

    //  验证码map
    private static Map<String, Map> verifyCodeMap = new HashMap();

    @Autowired
    HttpServletRequest request;
    @Autowired
    private ParkManagerDao parkManagerDao;
    @Autowired
    ManagerExpandDao managerExpandDao;
    @Autowired
    ManagerLinkDao managerLinkDao;

    @Override
    public IPage<ParkManagerDTO> page(ParkManagerSearchForm form) {
        IPage<ParkManagerDTO> iPage = parkManagerDao.list(form.getPage());

        return iPage;
    }

    @Override
    @Transactional
    public Map<String,String> add(ParkManagerAddForm form){
        Map<String,String> map = new HashMap<>();

        ParkManagerDTO managerDTO = parkManagerDao.getBymobilePhone(form.getMobilePhone());
        if (managerDTO != null){
            map.put("status","0");
            map.put("message","此手机号已经注册，请更换手机号");
            return map;
        }
        ParkManager parkManager = new ParkManager();
        BeanUtils.copyProperties(form, parkManager);
        parkManager.setIsOwner(0);
        parkManagerDao.insert(parkManager);

        ManagerLink managerLink = new ManagerLink();
        managerLink.setParkId(form.getParkId());
        managerLink.setParkManagerId(parkManager.getId());
        int insert = managerLinkDao.insert(managerLink);
        if (insert > 0){
            map.put("status","1");
            map.put("message","成功");
        } else {
            map.put("status","0");
            map.put("message","添加失败");
        }
        return map;
    }

    @Override
    public void delete(Long id){
        //  删除管理员关联的停车场
        ParkManagerDTO parkManagerDTO = parkManagerDao.getById(id);
        LambdaUpdateWrapper<ManagerLink> deleteWrapper = new LambdaUpdateWrapper();
        deleteWrapper.eq(ManagerLink::getParkManagerId, id);
        managerLinkDao.delete(deleteWrapper);

        //  不删车场主
        if(!parkManagerDTO.getIsOwner().equals(1)){
            //  删除管理员
            ParkManager parkManager = new ParkManager();
            parkManager.setId(id);
            parkManager.setIsDeleted(1);
            parkManagerDao.updateById(parkManager);
        }
    }

    @Override
    public void update(ParkManagerUpdateForm form){
        ParkManager parkManager = new ParkManager();
        BeanUtils.copyProperties(form, parkManager);

        parkManagerDao.updateById(parkManager);
    }

    @Override
    public ParkManagerDTO getById(Long id){
        ParkManagerDTO parkManagerDTO = parkManagerDao.getById(id);

        return parkManagerDTO;
    }

    /**
     * 发送短信验证码
     */
    @Override
    public Map<String, Object> sendVerifyCode(String phoneNumber) {

        /**根据mobilePhone查询车场管理员表*/
        ParkManagerDTO parkManagerDTO = parkManagerDao.getBymobilePhone(phoneNumber);
        if(parkManagerDTO == null){
            ExceptionUtil.authorizeException("用户不存在");
        }

        //  1、校验短信验证码模版是否正确
        //  查询短信模版
        String templateContent = ShortMsgUtil.querySmsTemplate("SMS_147915193");
        //  匹配${}
        Matcher matcher = Pattern.compile("\\$\\{[^\\{\\}]{1,}\\}").matcher(templateContent);
        List<String> templateVariables = new ArrayList<>();
        while(matcher.find()){
            templateVariables.add(matcher.group());
        }
        //  短信验证码模版变量错误，验证码模版有且只有一个变量
        if(templateVariables.size() != 1){
            ExceptionUtil.businessException("短信验证码模版变量错误，验证码模版有且只有一个变量");
        }

          //2、校验短信是否已经发送
        Map<String, Object> sendCodeMap = verifyCodeMap.get(phoneNumber);
        if(sendCodeMap != null && sendCodeMap.get("expire") != null){
            Date expire = (Date) sendCodeMap.get("expire");
            if(expire.getTime() > new Date().getTime()){
                ExceptionUtil.businessException("短信已经发送，请注意查收");
            }
        }

        //  3、发送短信
        Map<String, Object> paramMap = new HashMap<>();
        String verifyCode = String.valueOf((int)((Math.random()*9+1)*1000));
//        String verifyCode = "0000";
        paramMap.put("code", verifyCode); //  验证码
        log.info("验证码：" + verifyCode);
        //  发送短信
        Map sendMap = ShortMsgUtil.sendVerifyCode("SMS_147915193", phoneNumber, paramMap);
//        Map sendMap = new HashMap();
        sendMap.put("Code", "OK");
        if(sendMap.get("Code").equals("OK")){
            log.info("短信验证码发送成功");
            Date expire = DateTimeUtil.getCurrAfterSecondDate(new Date(), 30);
            Map<String, Object> codeMap = new HashMap();
            codeMap.put("code", verifyCode);
            codeMap.put("expire", expire);
            verifyCodeMap.put(phoneNumber, codeMap);

            return codeMap;
        } else {
            log.error("短信验证码发送失败");
            ExceptionUtil.businessException("短信验证码发送失败");
        }

        return null;
    }

    /**
     * 登录
     */
    @Override
    public AuthorizeVO login(LoginForm form) {
        Map<String, Object> codeMap = verifyCodeMap.get(form.getPhoneNumber());
        if(codeMap != null && form.getVerifyCode().equals(codeMap.get("code"))){
            Date expire = (Date) codeMap.get("expire");
            if(expire.getTime() < new Date().getTime()){
                ExceptionUtil.businessException("验证码已过期");
            }
            //  清除验证码
            verifyCodeMap.remove(form.getPhoneNumber());
            //  清除其他失效验证码
            for(Map.Entry<String, Map> entry: verifyCodeMap.entrySet()){
                Map value = entry.getValue();
                Date expireOther = (Date) value.get("expire");
                if(expireOther.getTime() < new Date().getTime()){
                    verifyCodeMap.remove(entry.getKey());
                }
            }

            ParkManagerDTO parkManagerDTO = parkManagerDao.getBymobilePhone(form.getPhoneNumber());
            if(parkManagerDTO == null){
                ExceptionUtil.authorizeException("用户不存在");
            }

            List<ManagerLinkDTO> linkDTOList = managerLinkDao.getParkByManageId(parkManagerDTO.getId());
            if (linkDTOList == null || linkDTOList.size() < 1){
                ExceptionUtil.authorizeException("您无车场，无法登录");
            }

            LoginUser loginUser = new LoginUser();
            loginUser.setCustomerId(parkManagerDTO.getId());
            loginUser.setNickname(parkManagerDTO.getNickname());
            loginUser.setOpenid(parkManagerDTO.getOpenid());
            String token = JwtUtil.createJWT(loginUser);

            AuthorizeVO authorizeVO = new AuthorizeVO();
            authorizeVO.setToken(token);
            authorizeVO.setUserId(parkManagerDTO.getId());
            //authorizeVO.setPhoneNumber(form.getPhoneNumber());
            return authorizeVO;
        } else {
            ExceptionUtil.businessException("验证码错误");
            return null;
        }
    }


    @Override
    @Transactional
    public ParkManagerDTO authorize(WeiXinAuthorizeForm weiXinAuthorizeForm) {
        LoginUser loginUser = JwtUtil.getLoginUser(request);

        String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + WeChatUtil.xcxAppId + "&secret=" + WeChatUtil.xcxAppSecret + "&js_code=" + weiXinAuthorizeForm.getCode() + "&grant_type=authorization_code";
        String response = HttpUtil.requestGet(url, null, null);
        JSONObject jsonObject = JSONObject.parseObject(response);
        if(jsonObject.get("openid") == null){
            ExceptionUtil.businessException("openid为空");
        }
        //  获取openid
        String openid = jsonObject.get("openid").toString();
        //  获取session_key
        //String sessionKey = jsonObject.get("session_key").toString();
        ParkManager parkManager = new ParkManager();
        parkManager.setId(loginUser.getCustomerId());
        parkManager.setOpenid(openid); //  openid
        parkManager.setAvatar(weiXinAuthorizeForm.getAvatar());   //  头像
        parkManager.setNickname(weiXinAuthorizeForm.getNickname());   //  昵称
        parkManagerDao.updateById(parkManager);

        ParkManagerDTO parkManagerDTO = parkManagerDao.getById(loginUser.getCustomerId());
        if(parkManagerDTO == null){
            ExceptionUtil.authorizeException("用户不存在");
        }
        return parkManagerDTO;
    }


}
